import { InterceptorManager } from './interceptor.js'; // 拦截器
import { dispatchRequest } from './request.js'; // 发起请求
import { merge, bind, forEach } from '../utils.js';

class Axios {
    constructor(config) {
        this.defaults = config;
        // 拦截器
        this.interceptors = {
            request: new InterceptorManager(),
            response: new InterceptorManager(),
        };
    }

    request(url, config) {
        // 检查参数
        if (typeof url === 'string') {
            config = config || {};
            config.url = url;
        } else {
            config = url || {};
        }

        // // 创建实例的配置与调用xxx请求方法的参数合并
        config = merge(this.defaults, config);

        // // 设置方法
        config.method = (
            config.method ||
            this.defaults.method ||
            'get'
        ).toLowerCase();

        let promise = null;

        // 请求拦截器
        const requestInterceptorsChain = [];
        this.interceptors.request.foreach(function (interceptor) {
            requestInterceptorsChain.unshift(
                interceptor.successful,
                interceptor.failed,
            );
        });

        // 响应拦截
        const responseInterceptorsChain = [];
        this.interceptors.response.foreach(function (interceptor) {
            responseInterceptorsChain.push(
                interceptor.successful,
                interceptor.failed,
            );
        });

        const chain = [dispatchRequest.bind(this), undefined];
        chain.unshift.apply(chain, requestInterceptorsChain);
        chain.push.apply(chain, responseInterceptorsChain);

        promise = Promise.resolve(config)

        /**
         * 执行对应的方法
         * 执行顺序为：1.请求拦截 > 2.发起请求 > 3.响应拦截
         */
        while (chain.length > 0) {
            const _resolve = chain.shift();
            const _reject = chain.shift();
            promise = promise.then(_resolve, _reject);
        }
        // 响应拦截器
        return promise;
    }

    /**
     * 注册请求方法
     */
    static registerRequestMethods() {
        const _context = this;
    }
}

// 注册请求方法
// 基础方法
forEach(['delete', 'get', 'head', 'options'], function register(method) {
    Axios.prototype[method] = function (url, config) {
        return this.request(
            merge(config || {}, {
                method: method,
                url,
                data: (config || {}).data,
            }),
        );
    };
});

// 修改数据的方法
forEach(['post', 'put', 'patch'], function register(method) {
    Axios.prototype[method] = function (url, data, config) {
        return this.request(
            merge(config || {}, {
                method: method,
                url,
                data: data || {},
            }),
        );
    };
});

export { Axios };
